﻿using System;
using System.Configuration;
using System.Threading;
using System.Threading.Tasks;
using xxpl1.GAE.Simple2Async;
using xxpl1.HTTP.Parser;
using xxpl1.HTTP.Runtime.Config;
using xxpl1.Log;
using xxpl1.Utils;

namespace xxpl1.HTTP.Runtime
{
    public class ProxyRuntime
    {
        private static readonly ILog logger = LogManager.GetLogger(typeof(ProxyRuntime));
        private static readonly HandlerPipeline pileline = new HandlerPipeline();
        private static readonly SimpleAsyncHandler2 simpleAsyncHandler2 = new SimpleAsyncHandler2();

        static ProxyRuntime()
        {
            HttpHandlerSection section = (HttpHandlerSection)ConfigurationManager.GetSection("HttpHandlerSection");

            foreach (HttpHandlerElement element in section.HttpHandler)
            {
                pileline.RegisterHanlder((IHttpRequestHandler)Activator.CreateInstance(Type.GetType(element.Type)));
            }
        }

        public static void Execute(HttpRequest request, HttpResponse response)
        {
            HandlerContext context = new HandlerContext(request, response);

            if (Settings.Instance.Async)
                simpleAsyncHandler2.BeginExecute(context);
            //ProcessRequest(context);
            else Task.Factory.StartNew(ProcessRequest, context);
            //ThreadPool.QueueUserWorkItem(ProcessRequest, context);
        }

        private static void ProcessRequest(object state)
        {
            try
            {
                HandlerContext context = state as HandlerContext;

                pileline.Execute(context);

                switch (context.Result)
                {
                    case HanlderReult.Ok:
                        context.Response.Close();
                        break;
                    default:
                        context.Response.Abort();
                        break;
                }

                Statistic.AddDownLoadTime(context.Request.ElapsedMs);
            }
            catch (Exception e)
            {
                logger.Error("Process Request Error", e);
            }
        }
    }
}
